package cn.com.scitc.licenseplateback.controller;

import biz.source_code.base64Coder.Base64Coder;
import cn.com.scitc.licenseplateback.dao.BookingWarehousingDao;
import cn.com.scitc.licenseplateback.dao.JUserTokenDao;
import cn.com.scitc.licenseplateback.dao.MembershipInformationDao;
import cn.com.scitc.licenseplateback.dao.VehicleAccessInformationDao;
import cn.com.scitc.licenseplateback.md5.MD5Util;
import cn.com.scitc.licenseplateback.model.BookingWarehousingEntity;
import cn.com.scitc.licenseplateback.model.MembershipInformationEntity;
import cn.com.scitc.licenseplateback.model.VehicleAccessInformationEntity;
import cn.com.scitc.licenseplateback.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class OffNavbar {

    /**
     * 日志
     */
    private Log log = LogFactory.getLog(getClass());

    /**
     * 缓存库
     */
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 预约入库信息
     */
    @Autowired
    private BookingWarehousingDao bookingWarehousingDao;


    /**
     * 车辆出入信息
     */
    @Autowired
    private VehicleAccessInformationDao vehicleAccessInformationDao;

    /**
     * 会员信息处理
     */
    @Autowired
    private MembershipInformationDao membershipInformationDao;

    /**
     * 加载公共方法
     */
    @Autowired
    private PublicFunction publicFunction;

    /**
     * MD5加密库
     */
    @Autowired
    private MD5Util md5Util;

    /**
     * 添加记住密码的信息
     */
    @Autowired
    private JUserTokenDao jUserTokenDao;



    /**
     * 获取用户的登录时间
     *
     * @param request 前端 token 令牌
     * @return 登录时间
     */
    @PostMapping("/getLoginTime")
    private String [] getLoginTime(HttpServletRequest request) {
        JSONObject jsonObject = publicFunction.getServerToken(request);
        MembershipInformationEntity member = membershipInformationDao.findbyMember(jsonObject.get("userId").toString());
        return new String[] {jsonObject.get("loginTime").toString(), String.valueOf(member.getGrade())};
    }

    /**
     * 退出登录
     *
     * @param request 前端 token
     */
    @GetMapping("/logOut")
    private void logOut(HttpServletRequest request) {
        String token = request.getHeader("cubelibrarytoken");
        redisUtil.del(token);
    }

    /**
     * 根据用户的选择，获取用户的相关预约相信
     *
     * @param request
     * @param status
     * @return
     */
    @PostMapping("/getUserBookingInfo")
    private Object getUserBookingInfo(HttpServletRequest request, int status) {
        JSONObject jsonObject = publicFunction.getServerToken(request);
        String userId = jsonObject.get("userId").toString();
        List<BookingWarehousingEntity> list = bookingWarehousingDao.findAllByIdNumber(userId, status);
        Object toJSON = JSON.toJSON(list);
        return toJSON;
    }

    /**
     * 验证检查手机验证码
     * @param code
     * @param request
     * @return
     */
    @PostMapping("/checkCode")
    private String checkCode(String code, HttpServletRequest request) {
        return publicFunction.checkPhoneVerificationCode(code, request);
    }

    /**
     * 车位预约后前端进行倒计时，计时结束会将车辆车牌号发送到时该
     * 方法进行 超时处理
     *
     * @param licensePlateNumber
     * @return
     */
    @PostMapping("/timerEnd")
    private Object timerEnd(String licensePlateNumber, String parking) {
         VehicleAccessInformationEntity byLicensePlateNumber = vehicleAccessInformationDao.findByLicensePlateNumber(licensePlateNumber);
        if (byLicensePlateNumber == null) {
            log.info("车辆: " + licensePlateNumber + " 超时未入库!!!");
            // 将车位信息进行释放
            publicFunction.analyzeParkingInformation(parking, "add");
            // 更新用户本次的预约状态为超时
            int plateStatusInfo = bookingWarehousingDao.updatePlateStatusInfo(3, licensePlateNumber);
            return plateStatusInfo;
        }
        return "";
    }


    /**
     * 根据请求头，获取用户登录 token 拿到用户 ID
     * 查询用户的所有信息
     *
     * @param request 请求头
     * @return 返回经过处理后的用户信息，在用户个人中心进行展示
     */
    @PostMapping("/getMemberAllInfo")
    private String getMemberAllInfo(HttpServletRequest request) {
        JSONObject serverToken = publicFunction.getServerToken(request);
        MembershipInformationEntity memberInfo = membershipInformationDao.findbyMember(serverToken.get("userId").toString());
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(memberInfo, SerializerFeature.WriteMapNullValue));
        List<Map> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("licensePlateNumber", jsonObject.get("licensePlateNumber"));
        map.put("balance", jsonObject.get("balance"));
        map.put("cellPhoneNumber", new String(new StringBuilder(jsonObject.get("cellPhoneNumber").toString()).replace(3, 9, "******")));
        map.put("registerTime", jsonObject.get("registerTime"));
        map.put("grade", jsonObject.get("grade"));
        map.put("name", jsonObject.get("name"));
        map.put("idNumber", new String(new StringBuilder(jsonObject.get("idNumber").toString()).replace(3, 16, "**************")));
        list.add(map);
        return JSONObject.toJSON(list).toString();
    }

    /**
     * 保存用户的头像
     *
     * @param Photo
     * @param request
     * @return
     */
    @PostMapping("/saveUserPhoto")
    private String saveUserPhoto(String Photo, HttpServletRequest request) {
        String[] userPhotoFile = publicFunction.getUserPhotoFilePath(request);

        new Runnable() {
            @Override
            public void run() {
                FileWriter fw = null;
                try {
                    // FileWriter 就是牛，如果文件名 的文件不存在，先创建再读写;存在的话直接追加写,关键字true表示追加
                    fw = new FileWriter(userPhotoFile[0] + "/" + userPhotoFile[1], false);
                    fw.append(Photo);
                    fw.flush();
                    fw.close();
                } catch (IOException e) {
                    try {
                        fw.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    e.printStackTrace();
                }
            }
        }.run();


        return "success";
    }

    /**
     * 读取用户的头像
     *
     * @param request
     * @return
     */
    @PostMapping("/readUserPhoto")
    private String readUserPhoto(HttpServletRequest request) {
        String[] userPhotoFile = publicFunction.getUserPhotoFilePath(request);
        File file = new File(userPhotoFile[0] + "/" + userPhotoFile[1]);
        if (!file.exists()) {
            return "";
        }
        StringBuilder img = new StringBuilder();
        try {
            FileReader fr = new FileReader(userPhotoFile[0] + "/" + userPhotoFile[1]);

            char[] chars = new char[1024];
            int ch = 0;
            while ((ch = fr.read(chars)) != -1) {
                img.append(chars, 0, ch);
            }
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return img.toString();
    }

    /**
     * 根据用户传入的请求头，获取用户的手机号
     *
     * @param request 请求头
     * @return 手机号
     */
    @PostMapping("/getUserPhoneNumber")
    private String getUserPhoneNumber(HttpServletRequest request) {
        JSONObject serverToken = publicFunction.getServerToken(request);
        MembershipInformationEntity memberInfo = membershipInformationDao.findbyMember(serverToken.get("userId").toString());
        if (memberInfo == null) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return memberInfo.getCellPhoneNumber();
    }

    /**
     * 根据用户传入的 旧手机号、新手机号、请求头
     * 实现用户的手机号 更换
     *
     * @param newPhone 新手机号
     * @param request  请求头
     * @return success or error
     */
    @PostMapping("/updateUserPhoneNumber")
    private String updateUserPhoneNumber(String newPhone, HttpServletRequest request) {
        JSONObject serverToken = publicFunction.getServerToken(request);
        String userId = serverToken.get("userId").toString();
        int number = membershipInformationDao.updateUserPhoneNumber(newPhone, userId);
        if (number != 1) {
            return "error";
        }
        return "success";
    }

    @PostMapping("/updateUserPass")
    private String updateUserPass(String info, HttpServletRequest request) {
        String Base64Info = Base64Coder.decodeString(info);
        JSONObject jsonObject = JSONObject.parseObject(Base64Info);
        /**
         * 1.验证 验证码是否正确
         * 2.根据用户请求头身份证号 对数据库中快速定位到该用户，并获取加密后的密码与盐
         * 3.对用户旧密码进行加密处理
         * 4.对加密后的旧密码进行与数据库中的密码进行匹对
         * 5.加密新密码，产生新盐
         * 6.更新密码
         * 7.强制用户下线
         * 8.清空自动登录
         */
        //1.验证 验证码是否正确
        String phoneNumber = jsonObject.get("phoneNumber").toString();
        String serverVer = redisUtil.get(phoneNumber).toString();
        if (!jsonObject.get("captcha").equals(serverVer)) {
            return "Verification code error";
        }
        //2.根据用户请求头身份证号 对数据库中快速定位到该用户，并获取加密后的密码与盐
        JSONObject serverToken = publicFunction.getServerToken(request);
        String userId = serverToken.get("userId").toString();
        MembershipInformationEntity memberInfo = membershipInformationDao.findbyMember(userId);
        //3.对用户旧密码进行加密处理
        String oldPassMd5 = md5Util.FINALPASS(jsonObject.get("oldPass").toString(), memberInfo.getStal());
        //4.对加密后的旧密码进行与数据库中的密码进行匹对
        if (!oldPassMd5.equals(memberInfo.getPassword())) {
            return "Old password error";
        }
        //6.更新密码
        String stal = md5Util.randomSalt();
        String confirmNewPassMd5 = md5Util.FINALPASS(jsonObject.get("confirmNewPass").toString(), stal);
        memberInfo.setPassword(confirmNewPassMd5);
        memberInfo.setStal(stal);
        MembershipInformationEntity save = membershipInformationDao.save(memberInfo);
        if (save == null) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //7.强制用户下线
        redisUtil.del(request.getHeader("cubelibrarytoken"));

        //8.清空自动登录
        int deleteAutoLoginInfo = jUserTokenDao.deleteByUserId(Base64Coder.encodeString(userId));

        return "success";
    }


    @Test
    public void test() {
        String str = "[{\"loginTime\":\"2019-10-26 04:09:27\",\"Driver\":\"MOBILE\",\"userId\":\"511521199807076171\"}]";
        JSONArray jsonArray = JSONArray.parseArray(str);
        log.info(jsonArray);
        JSONObject jsonObject = JSONObject.parseObject(jsonArray.get(0).toString());
        System.out.println(jsonObject.get("loginTime").toString());
    }
}
